﻿/*
 * Created by SharpDevelop.
 * User: Intel
 * Date: 28.11.2014
 * Time: 9:29
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Region.Utils
{
  public class EngineConfig
  {
    EngineConfig m_parent=null;
    public virtual T getValue<T>(String Name,T Default)
    {
      if (m_parent!=null)
        return m_parent.getValue(Name,Default);
      return Default;
    }
    public virtual void setValue<T>(String Name,T Value){return ;}
    public virtual Boolean isValue<T>(String Name)
    {      
        if (m_parent!=null)
        return m_parent.isValue<T>(Name);
      return false;
    }
    /*
    public virtual Boolean getValueBoolean(String Name,Boolean Default = false)
    {
      if (m_parent!=null)
        return m_parent.getValueBoolean(Name,Default);
      return Default;
    }
    public virtual Int32 getValueInt(String Name,Int32 Default = 0)
    {
      if (m_parent!=null)
        return m_parent.getValueInt(Name,Default);
      return Default;
    }
    public virtual String getValueString(String Name,String Default = "")
    {
      if (m_parent!=null)
        return m_parent.getValueString(Name,Default);

      return Default;
    }
    public virtual List<String> getValueStringList(String Name,List<String> Default = null)
    {
      if (m_parent!=null)
        return m_parent.getValueStringList(Name,Default);
      return new List<String>(Default);
    }
    public virtual void setValue(String Name,Boolean Value){return ;}
    public virtual void setValue(String Name,Int32 Value){return ;}
    public virtual void setValue(String Name,String Value){return ;}
    public virtual void setValue(String Name,List<String> Value){return ;}
    */
    public virtual void save(){return ;}
    public EngineConfig(EngineConfig parent=null)
    {
      m_parent = parent;
    }
    
  }
  /// <summary>
  /// Description of XMLConfig.
  /// </summary>
  public class XMLConfig: EngineConfig
  {
    XDocument m_Doc;
    String m_FileName;
    bool edit = false;
    
    protected XElement createParam(String Name,String Type)
    {
      XElement el = findParam(Name, Type);
      if (el==null)
      {
        el = new XElement("param");
        el.Add(new XAttribute("name",Name));
        el.Add(new XAttribute("type",Type));

        m_Doc.Root.Add(el);
      }
      return el;
    }
    protected XElement findParam(String Name,String Type)
    {
      foreach (XElement el in m_Doc.Root.Elements())
        if (el.Attribute("name").Value == Name && el.Attribute("type").Value == Type)
          return el;
      return null;
    }

    public XMLConfig(String FileName="./config.xml",EngineConfig parent=null): base(parent)
    {
      m_FileName = FileName;
      try
      {
        if (File.Exists(m_FileName))
        {
          m_Doc = XDocument.Load(m_FileName);          
          return;
        }
      }
      catch(Exception){}
      m_Doc = new XDocument(new XElement("parametrs"));
    }

    public override T getValue<T>(String Name,T Default)
    {
      XElement el = findParam(Name, typeof(T).Name);
      if (el!=null)
      {
        if (typeof(T).Name=="String[]")
        {
          var list = new List<String>();
          foreach (XElement e in el.Elements())
            if (e.Name=="item")
              list.Add(e.Value);
          return (T)(Object)list.ToArray();
        }
        return (T)System.Convert.ChangeType(el.Value, typeof(T)); 
      }
      return base.getValue<T>(Name,Default);
    }
    public override Boolean isValue<T>(String Name)
    {
        XElement el = findParam(Name, typeof(T).Name);
        if (el != null) return true;
        return base.isValue<T>(Name); ;
    }
    public override void setValue<T>(String Name,T Value)
    {
      XElement el = createParam(Name,typeof(T).Name);
      edit = true;
      if (typeof(T).Name=="String[]" ||  typeof(T).FullName==typeof(List<String>).FullName)
      {
        el.RemoveNodes();
        foreach(String S in (String[])(Object)Value)
        {
          var item = new XElement("item");
          item.Value = S;
          el.Add(item);
        }
        return;
      }
      el.Value = (String)System.Convert.ChangeType(Value, typeof(String)); 
    }
    /*
    public override Boolean getValueBoolean(String Name,Boolean Default = false)
    {
      XElement el = findParam(Name, "Boolean");
      if (el!=null)
      {
        Boolean Value;
        Boolean.TryParse(el.Value,out Value);
        return Value;
      }
      return base.getValueBoolean(Name,Default);
    }
    public override Int32 getValueInt(String Name,Int32 Default = 0)
    {
      XElement el = findParam(Name, "Int32");
      if (el!=null)
      {
        Int32 Value;
        Int32.TryParse(el.Value,out Value);
        return Value;
      }
      return base.getValueInt(Name,Default);
    }
    public override String getValueString(String Name,String Default = "")
    {
      XElement el = findParam(Name, "String");
      return (el!=null)?el.Value:base.getValueString(Name,Default);
    }
    public override List<String> getValueStringList(String Name,List<String> Default = null)
    {
      XElement el = findParam(Name, "StringList");
      if (el!=null)
      {
        var list = new List<String>();
        foreach (XElement e in el.Elements())
          if (e.Name=="item")
            list.Add(e.Value);
        return list;
      }
      if (Default==null) 
        Default = new List<String>();
      return base.getValueStringList(Name,Default); 
    }
    public override void setValue(String Name,Boolean Value)
    {
      XElement el = createParam(Name,"Boolean");
      edit = true;
      
      el.Value = Value.ToString();
    }
    public override void setValue(String Name,Int32 Value)
    {
      XElement el = createParam(Name,"Int32");
      edit = true;
      el.Value = Value.ToString();
    }
    public override void setValue(String Name,String Value)
    {
      edit = true;
      XElement el = createParam(Name,"String");
      el.Value = Value;
    }
    public override void setValue(String Name,List<String> Value)
    {
      edit = true;
      XElement el = createParam(Name,"StringList");
      el.RemoveNodes();
      foreach(String S in Value)
      {
        var item = new XElement("item");
        item.Value = S;
        el.Add(item);
      }
        
    }*/
    public override void save()
    {
      if (edit) m_Doc.Save(m_FileName);
      edit = false;
    }
  }
}
